package com.chuangyiruanke.util;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.sun.xml.internal.bind.v2.util.ByteArrayOutputStreamEx;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;

/**
 * 生成二维码图片
 */
public class QRCodeUtil {
    private static final int BLACK = 0xff000000;
    private static final int WHITE = 0xFFFFFFFF;

    /**
     * 生成QRCode二维码<br>
     * 在编码时需要将com.google.zxing.qrcode.encoder.Encoder.java中的<br>
     * static final String DEFAULT_BYTE_MODE_ENCODING = "ISO8859-1";<br>
     * 修改为UTF-8，否则中文编译后解析不了<br>
     *
     * @param contents    二维码的内容
     * @param formatName  生成二维码图片的格式：png,jpeg,gif等格式
     * @param format      qrcode码的生成格式
     * @param width       图片宽度
     * @param height      图片高度
     */
    public static ByteBuffer encode(String contents, String formatName, BarcodeFormat format, int width, int height) {
        try {
            contents = new String(contents.getBytes("UTF-8"), "ISO-8859-1");
            BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, format, width, height);
            BufferedImage image = toBufferedImage(bitMatrix);
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            ImageIO.write(image, formatName, stream);
            return ByteBuffer.wrap(stream.toByteArray());
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * 生成二维码图片<br>
     *
     * @param matrix
     * @param format 图片格式
     * @return 生成二维码图片位置
     * @throws IOException
     */
    private static void write(BitMatrix matrix, String format, OutputStream outputStream) throws IOException {
        BufferedImage image = toBufferedImage(matrix);
        ImageIO.write(image, format, outputStream);
    }

    /**
     * 生成QRCode二维码<br>
     * 在编码时需要将com.google.zxing.qrcode.encoder.Encoder.java中的<br>
     * static final String DEFAULT_BYTE_MODE_ENCODING = "ISO8859-1";<br>
     * 修改为UTF-8，否则中文编译后解析不了<br>
     *
     * @param contents    二维码的内容
     * @param formatName 生成二维码图片的格式：png,jpeg,gif等格式
     * @param format      qrcode码的生成格式
     * @param width       图片宽度
     * @param height      图片高度
     */
    public static void writeToStream(String contents, String formatName, BarcodeFormat format, int width, int height, OutputStream outputStream) {
        try {
            contents = new String(contents.getBytes("UTF-8"), "ISO-8859-1");
            BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, format, width, height);
            write(bitMatrix, formatName, outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成二维码内容<br>
     *
     * @param matrix
     * @return
     */
    private static BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
            }
        }
        return image;
    }
}
